<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <base data-ice="baseUrl" href="../../">
  <title data-ice="title">Math3d/Line.js | webpack-demo1</title>
  <link type="text/css" rel="stylesheet" href="css/style.css">
  <link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
  <script src="script/prettify/prettify.js"></script>
  <script src="script/manual.js"></script>
</head>
<body class="layout-container" data-ice="rootContainer">

<header>
  <a href="./">Home</a>
  
  <a href="identifiers.html">Reference</a>
  <a href="source.html">Source</a>
  
  <div class="search-box">
  <span>
    <img src="./image/search.png">
    <span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
  </span>
    <ul class="search-result"></ul>
  </div>
</header>

<nav class="navigation" data-ice="nav"><div>
  <ul>
    
  <li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/Math3d/Circle.js~Circle.html">Circle</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/Math3d/CircleAndPoint.js~CircleAndPoint.html">CircleAndPoint</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/Math3d/Common.js~Common.html">Common</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/Math3d/Line.js~Line.html">Line</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/Math3d/LineAndCircle.js~LineAndCircle.html">LineAndCircle</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/Math3d/LineAndPoint.js~PointAndLine.html">PointAndLine</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/Math3d/Point.js~Point.html">Point</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-EPSILON">EPSILON</a></span></span></li>
</ul>
</div>
</nav>

<div class="content" data-ice="content"><h1 data-ice="title">Math3d/Line.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">// &#x4F9D;&#x8D56;:SylLine
export default class Line {
  /**-------------------------&#x4F4D;&#x7F6E;&#x5173;&#x7CFB;---------------------- */
  /**
   * &#x5224;&#x65AD;&#x4E24;&#x6761;&#x7EBF;&#x662F;&#x5426;&#x5782;&#x76F4;
   * @param {*} v1
   * @param {*} v2
   * @note &#x5411;&#x91CF;&#x5185;&#x79EF;&#xFF1A;a*b=|a||b|*cos(Y) &#x5F53;cos&#x4E3A;0&#x65F6;&#x6B63;&#x4EA4;(90,-90&#x5782;&#x76F4;)
   */
  static isOrthogonal(v1, v2) {
      if (Math3D.isZeroVector(v1) || Math3D.isZeroVector(v2)) return false

      const ret = v1.clone().dot(v2)
      if (Math.abs(ret - 0) &lt; EPSILON) return true
      else return false
  }

  /**
   * &#x5224;&#x65AD;&#x4E24;&#x6761;&#x7EBF;&#x662F;&#x5426;&#x5E73;&#x884C;
   * @param {*} v1
   * @param {*} v2
   */
  static isParallel(v1, v2) {
      if (Math3D.isZeroVector(v1) || Math3D.isZeroVector(v2)) return false

      let v = v1.clone().cross(v2)
      return Math3D.isZeroVector(v);
  }

  /**
   * &#x8BA1;&#x7B97;&#x4E24;&#x6761;&#x7EBF;&#x7684;&#x4EA4;&#x70B9;,&#x6CA1;&#x6709;&#x4EA4;&#x70B9;&#x8FD4;&#x56DE; null
   */
  static lineIntersec2(s1, e1, s2, e2) {
      let line1 = SylLine.create(Object.values(s1), Object.values(e1.clone().sub(s1)))
      let line2 = SylLine.create(Object.values(s2), Object.values(e2.clone().sub(s2)))
      let ret = line1.intersectionWith(line2)
      if (!ret) return null
      else return new THREE.Vector3().fromArray(ret.elements)
  }

  /**
   * &#x8BA1;&#x7B97;&#x4E24;&#x6761;&#x7EBF;&#x7684;&#x4EA4;&#x70B9;,&#x6CA1;&#x6709;&#x4EA4;&#x70B9;&#x8FD4;&#x56DE; null
   */
  static lineAndLineIntersec(a, b, c, d) {
      // todo:&#x5148;&#x5224;&#x65AD;&#x6709;&#x65E0;&#x4EA4;&#x70B9;
      let p1 = Math3D.projection(c, a, b)
      let p2 = Math3D.projection(d, a, b)
      let d1 = p1.distanceTo(c)
      let d2 = p2.distanceTo(d)
      let s = d1 / d2
      let cd = c.distanceTo(d)
      let ck = cd * s / (s + 1)
      let t = ck / cd

      let cdV = d.clone().sub(c)
      let k = cdV.multiplyScalar(t).add(c)
      return k
  }

  /**---------------------------&#x6570;&#x91CF;&#x5173;&#x7CFB;---------------------- */
  /**
   * &#x8BA1;&#x7B97;&#x7EBF;&#x6BB5;&#x4E4B;&#x95F4;&#x7684;&#x8DDD;&#x79BB;
   * @param {*} s1
   * @param {*} e1
   * @param {*} s2
   * @param {*} e2
   * @note https://gist.github.com/cuberoot/b5047c83cf277fee1b82
   * @note http://geomalgorithms.com/a07-_distance.html
   *
   */
  static distanceBetweenLines(startPt1, endPt1, startPt2, endPt2) {
      var u, v, w, a, b, c, d, e, D, sc, sN, sD, tc, tN, tD;

      u = new THREE.Vector3();
      u.subVectors(endPt1, startPt1);
      v = new THREE.Vector3();
      v.subVectors(endPt2, startPt2);
      w = new THREE.Vector3();
      w.subVectors(startPt1, startPt2);

      a = u.dot(u);           // always &gt;= 0
      b = u.dot(v);
      c = v.dot(v);           // always &gt;= 0
      d = u.dot(w);
      e = v.dot(w);

      D = (a * c) - (b * b);  // always &gt;= 0
      sD = D;                 // default sD = D &gt;= 0
      tD = D;                 // default tD = D &gt;= 0

      // compute the line parameters of the two closest points
      if (D &lt; EPSILON) {
          // the lines are almost parallel
          sN = 0.0;         // force using point P0 on segment S1
          sD = 1.0;         // to prevent possible division by 0.0 later
          tN = e;
          tD = c;
      }
      else {
          // get the closest points on the infinite lines
          sN = (b * e - c * d);
          tN = (a * e - b * d);
          if (sN &lt; 0.0) {
              // sc &lt; 0 =&gt; the s=0 edge is visible
              sN = 0.0;
              tN = e;
              tD = c;
          }
          else if (sN &gt; sD) {
              // sc &gt; 1  =&gt; the s=1 edge is visible
              sN = sD;
              tN = e + b;
              tD = c;
          }
      }

      if (tN &lt; 0.0) {
          // tc &lt; 0 =&gt; the t=0 edge is visible
          tN = 0.0;
          // recompute sc for this edge
          if (-d &lt; 0.0) {
              sN = 0.0;
          }
          else if (-d &gt; a) {
              sN = sD;
          }
          else {
              sN = -d;
              sD = a;
          }
      }
      else if (tN &gt; tD) {
          // tc &gt; 1  =&gt; the t=1 edge is visible
          tN = tD;
          // recompute sc for this edge
          if ((-d + b) &lt; 0.0) {
              sN = 0;
          }
          else if ((-d + b) &gt; a) {
              sN = sD;
          }
          else {
              sN = (-d + b);
              sD = a;
          }
      }

      // finally do the division to get sc and tc
      sc = (Math.abs(sN) &lt; EPSILON ? 0.0 : sN / sD);
      tc = (Math.abs(tN) &lt; EPSILON ? 0.0 : tN / tD);

      // get the difference of the two closest points
      var sc_mult_u = new THREE.Vector3();
      sc_mult_u.copy(u);
      sc_mult_u.multiplyScalar(sc);
      var tc_mult_v = new THREE.Vector3();
      tc_mult_v.copy(v);
      tc_mult_v.multiplyScalar(tc);
      var dP = new THREE.Vector3();
      dP.copy(w);
      dP.add(sc_mult_u);
      dP.sub(tc_mult_v);

      return dP.length();   // return the closest distance
  }

  /**
   * &#x8BA1;&#x7B97;&#x7EBF;&#x6BB5;&#x4E4B;&#x95F4;&#x7684;&#x8DDD;&#x79BB;,&#x5B9E;&#x73B0;&#x65B9;&#x5F0F;2
   * @param {*} segA
   * @param {*} segB
   * @param {*} lineA
   * @param {*} lineB
   * @note https://lianming.gitee.io/geometrytest/%E7%BA%BF%E6%AE%B5%E6%9C%80%E5%B0%8F%E8%B7%9D%E7%A6%BB/
   */
  static distanceBetweenLines2(segA, segB, lineA, lineB) {
      let lineBAAxis = lineB.clone().sub(lineA).normalize();
      let inPlaneA = segA.clone().sub(lineA).projectOnPlane(lineBAAxis).add(lineA);
      let inPlaneB = segB.clone().sub(lineA).projectOnPlane(lineBAAxis).add(lineA);
      let inPlaneBA = inPlaneB.clone().sub(inPlaneA);
      let t = lineA.clone().sub(inPlaneA).dot(inPlaneBA) / inPlaneBA.lengthSq();
      let rayPoint = segA.clone().lerp(segB, Math.min(Math.max(t, 0), 1));
      let ab = Math3D.closestToSegment(rayPoint, segA, segB)
      let cd = Math3D.closestToSegment(ab, lineA, lineB)
      return ab.distanceTo(cd)
  }

    /**
     * &#x5224;&#x65AD;&#x4E24;&#x6761;&#x7EBF;&#x6BB5;&#x662F;&#x5426;&#x6709;&#x4EA4;&#x70B9;
     * @param {*} p0
     * @param {*} p1
     * @param {*} p2
     * @param {*} p3
     */
    static intersect(p1, p2, p3, p4) {
        // p3,p4&#x5728;p1,p2&#x7684;&#x4E24;&#x4FA7;
        let t1 = Math3D.ccw(p1, p2, p3)
        let t2 = Math3D.ccw(p1, p2, p4)
        let t3 = Math3D.ccw(p3, p4, p1)
        let t4 = Math3D.ccw(p3, p4, p2)
        if (t1 * t2 &lt; 0 &amp;&amp; t3 * t4 &lt; 0) {
            return true
        } else {
            return false
        }
    }
}
</code></pre>

</div>

<footer class="footer">
  Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(1.1.0)</span><img src="./image/esdoc-logo-mini-black.png"></a>
</footer>

<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>
